﻿using JMI_Nucleo.Enumerador;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Text;

namespace JMI_Nucleo.Classe
{
    public class UtilSQL
    {
        #region Local
        private String tabela;
        private String strCampo;
        private String strValor;
        private String campoChave;
        private String filtro;
        private String schema;
        #endregion

        #region Propriedade
        public DbConnection Conexao { get; set; }
        public string Tabela
        {
            get { return tabela; }
            set { tabela = value; }
        }
        public string CampoChave
        {
            get { return campoChave; }
            set { campoChave = value; }
        }
        public string Filtro
        {
            get { return filtro; }
            set { filtro = value; }
        }
        public string Schema
        {
            get { return schema; }
            set { schema = value; }
        }
        public short CodigoEmpresa { get; set; }
        #endregion

        public UtilSQL()
        {
            schema = "public";
        }
        #region Comandos SQL
        public string GeraSimpleSQL(string[] mtzOrdenacao)
        {
            string _sql = String.Empty;
            short nroCampo = 0;
            short i = 0;
            StringBuilder arrSQL = new StringBuilder();
        
            if (!Schema.Equals("public"))
            {
                string s = Schema + "." + Tabela;
                Tabela = s;
            }
            arrSQL.Append("SELECT * FROM ");
            arrSQL.Append(Tabela);
            if (mtzOrdenacao != null)
            {
                if (mtzOrdenacao.Length > 0)
                {
                    arrSQL.Append(" ORDER BY ");
                    nroCampo = (short)mtzOrdenacao.Length;
                    foreach (string e in mtzOrdenacao)
                    {
                        i++;
                        if (i < nroCampo)
                            arrSQL.Append(e + ", ");
                        else
                            arrSQL.Append(e);
                    }
                }
            }
            _sql = arrSQL.ToString();
            return _sql;
        }
        public string GeraComandoSQL(byte Tipo, bool UsaSequenciador = false, bool GeraParametroEmpresa = true)
        {
            if (!Schema.Equals("public"))
            {
                string s = String.Empty;
                if (!Tabela.Contains("."))
                {
                    s = Schema + "." + Tabela;
                    Tabela = s;
                }
            }
            string _sql = String.Empty;
            /// <summary>
            /// Parametro Tipo
            /// 1 - Inclusão
            /// 2 - Alteração
            /// 3 - Exclusão
            /// </summary>
            string nomeCampo = String.Empty;
            strCampo = String.Empty;
            strValor = String.Empty;
            StringBuilder cmdSQL = new StringBuilder();
            var schema = GetSchema();

            switch (Tipo)
            {
                case 1:
                    {
                        cmdSQL.Append("INSERT INTO " + Tabela + "(");

                        short nroCampo;
                        nroCampo = (short)schema.Rows.Count;
                        short x = 0;
                        foreach (DataRow campo in schema.Rows)
                        {
                            x++;
                            nomeCampo = campo["ColumnName"].ToString();
                            if (nomeCampo.ToLower() == "codigo" && UsaSequenciador) { continue; }
                            if (x < nroCampo)
                            {
                                strCampo += nomeCampo + ", ";
                                strValor += ":" + nomeCampo + ", ";
                            }
                            else
                            {
                                strCampo += nomeCampo;
                                strValor += ":" + nomeCampo;
                            }
                        }
                        cmdSQL.Append(strCampo + ")");
                        cmdSQL.Append(" VALUES (" + strValor + ")");

                        _sql = cmdSQL.ToString();
                    }
                    break;
                case 2:
                    {
                        cmdSQL.Append("UPDATE " + Tabela + " SET ");

                        short nroCampo;
                        nroCampo = (short)schema.Rows.Count;
                        short x = 0;
                        foreach (DataRow campo in schema.Rows)
                        {
                            x++;
                            nomeCampo = campo["ColumnName"].ToString();
                            if (x < nroCampo)
                            {
                                if (x > 1)
                                    cmdSQL.Append(nomeCampo + " =:" + nomeCampo + ", ");
                            }
                            else
                                cmdSQL.Append(nomeCampo + " =:" + nomeCampo);
                        }
                        cmdSQL.Append(" WHERE " + CampoChave + " =:PAR_" + CampoChave.ToUpper());
                        if (GeraParametroEmpresa)
                        {
                            cmdSQL.Append(" AND empresa = " + CodigoEmpresa.ToString());
                        }
                        _sql = cmdSQL.ToString();
                    }
                    break;
                case 3:
                    {
                        cmdSQL.Append("DELETE FROM " + Tabela);
                        cmdSQL.Append(" WHERE " + CampoChave + " =:PAR_" + CampoChave.ToUpper());
                        if (GeraParametroEmpresa)
                        {
                            cmdSQL.Append(" AND empresa = " + CodigoEmpresa.ToString());
                        }
                        _sql = cmdSQL.ToString();
                    }
                    break;
            }

            return _sql;
        }
        public string GeraSelectSQL(string[] mtzCampo, string[] mtzOrdenacao, bool GeraParametroEmpresa = true)
        {
            short nroCampo = (short)mtzCampo.Length;
            short i = 0;
            StringBuilder arrSQL = new StringBuilder();
            arrSQL.Append("SELECT ");
            foreach (string e in mtzCampo)
            {
                if (e.Contains("*"))
                {
                    arrSQL.Append(e);
                    break;
                }
                i++;
                if (i < nroCampo)
                    arrSQL.Append(e + ", ");
                else
                    arrSQL.Append(e);
            }
            arrSQL.Append(" FROM " + Tabela);
            if (Tabela.ToLower().Equals("empresa")) // Quando for a tabela empresa
            {
                if (!String.IsNullOrEmpty(Filtro))
                    arrSQL.Append(" WHERE " + Filtro);
                else if (!String.IsNullOrEmpty(CampoChave))
                    arrSQL.Append(" WHERE " + CampoChave + " =:PAR_" + CampoChave.ToUpper());
            }
            else
            {
                if (!String.IsNullOrEmpty(CampoChave))
                {
                    arrSQL.Append(" WHERE " + CampoChave + " =:PAR_" + CampoChave.ToUpper());
                    if (GeraParametroEmpresa)
                        arrSQL.Append(" AND empresa = " + CodigoEmpresa.ToString());
                }
                else if (!String.IsNullOrEmpty(Filtro)) // Se não existir filtro usa o código da empresa
                {
                    arrSQL.Append(" WHERE " + Filtro);
                    if (GeraParametroEmpresa)
                        arrSQL.Append(" AND empresa = " + CodigoEmpresa.ToString());
                }
                else
                {
                    arrSQL.Append(" WHERE empresa = " + CodigoEmpresa.ToString());
                }
            }
            if (mtzOrdenacao != null)
            {
                if (mtzOrdenacao.Length > 0)
                {
                    arrSQL.Append(" ORDER BY ");
                    nroCampo = (short)mtzOrdenacao.Length;
                    foreach (string e in mtzOrdenacao)
                    {
                        i++;
                        if (i < nroCampo)
                            arrSQL.Append(e + ", ");
                        else
                            arrSQL.Append(e);
                    }
                }
            }
            string _sql = arrSQL.ToString();
            return _sql;
        }
        public string GetComandoUpdateSQL(string[] Campos)
        {
            short nroCampo = (short)Campos.Length;
            short i = 0;
            StringBuilder arrSQL = new StringBuilder();
            arrSQL.Append("UPDATE " + Tabela + " SET ");
            foreach (string e in Campos)
            {
                i++;
                if (i < nroCampo)
                    arrSQL.Append(e + " =:" + e + ", ");
                else
                    arrSQL.Append(e + " =:" + e);
            }
            arrSQL.Append(" WHERE " + CampoChave + " =:PAR_" + CampoChave.ToUpper());
            string _sql = arrSQL.ToString();
            return _sql;
        }        
        #endregion

        #region Metodos privados
        private DataTable GetSchema()
        {
            DbDataReader dr = null;
            DbCommand comando = null;
            DataTable schema = null;
            try
            {
                comando = Conexao.CreateCommand();
                comando.CommandType = CommandType.Text;
                comando.CommandText = "SELECT * FROM " + Tabela;
                dr = comando.ExecuteReader(CommandBehavior.KeyInfo);
                schema = dr.GetSchemaTable();
            }
            finally
            {
                dr.Close();
                comando.Dispose();
            }
            return schema;
        }
        private ArrayList GetCampoTabela()
        {
            ArrayList lstCampo = new ArrayList();
            DbCommand comando = Conexao.CreateCommand();
            comando.CommandType = CommandType.Text;
            comando.CommandText = "SELECT * FROM " + Tabela;
            DbDataReader dr = comando.ExecuteReader(CommandBehavior.KeyInfo);
            var Schema = dr.GetSchemaTable();
            dr.Close();
            string nomeCampo;

            foreach (DataRow campo in Schema.Rows)
            {
                nomeCampo = campo["ColumnName"].ToString();
                lstCampo.Add(nomeCampo);
            }
            return lstCampo;
        }        
        #endregion
    }
}
